import Vue from 'vue'
import axios from 'axios'
// import store from '@/store'
import { isArray } from '@/utils/validate'
import router from '@/router'
import { Toast } from 'vant'
import {
  baseURL,
  contentType,
  messageName,
  requestTimeout,
  statusName,
  dataName,
  successCode,
  debounce,
} from '@/config'
// import qs from 'qs'

let loadingInstance

// 操作正常Code数组
const codeVerificationArray = isArray(successCode)
  ? [...successCode]
  : [...[successCode]]

const CODE_MESSAGE = {
  200: '服务器成功返回请求数据',
  201: '新建或修改数据成功',
  202: '一个请求已经进入后台排队(异步任务)',
  204: '删除数据成功',
  400: '发出信息有误',
  401: '用户没有权限(令牌失效、用户名、密码错误、登录过期)',
  402: '前端无痛刷新token',
  403: '用户得到授权，但是访问是被禁止的',
  404: '访问资源不存在',
  406: '请求格式不可得',
  410: '请求资源被永久删除，且不会被看到',
  500: '服务器发生错误',
  502: '网关错误',
  503: '服务不可用，服务器暂时过载或维护',
  504: '网关超时',
}
const handleData = ({ config, data, status, statusText }) => {
  if (loadingInstance) loadingInstance.clear()
  // 若data.code存在，覆盖默认code
  let code = data ? data[statusName] : status
  // console.log(data)
  // 若code属于操作正常code，则status修改为200
  if (codeVerificationArray.indexOf(data[statusName]) + 1) code = 200
  switch (code) {
    case 0:
    case 200:
      // 业务层级错误处理，以下是假定restful有一套统一输出格式(指不管成功与否都有相应的数据格式)情况下进行处理
      // 例如响应内容：
      // 错误内容：{ code: 1, msg: '非法参数' }
      // 正确内容：{ code: 200, data: {  }, msg: '操作正常' }
      // return data
      return dataName ? data[dataName] : data
    case 400403:
      router.push({ path: '/403' }).then(() => {})
      break
    default:
      // 轻提示类型 这种错误需要让用户感知
      Toast(data[messageName])
      // 如果是注册的 跳转到认证失败页面
      if (config.url == '/register') {
        // const { redirect } = route.query
        return data
      }
  }
  console.log(config.url)
  // 异常处理
  // 若data.msg存在，覆盖默认提醒消息
  const errMsg = `${config.url} 后端接口 ${code} 异常：${
    data && data[messageName]
      ? data[messageName]
      : CODE_MESSAGE[code]
      ? CODE_MESSAGE[code]
      : statusText
  }`
  const err = new Error(errMsg)
  return Promise.reject(err)
}

// create an axios instance
const service = axios.create({
  baseURL: baseURL, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: requestTimeout, // request timeout
  headers: {
    'Content-Type': contentType,
  },
})

// request interceptor
service.interceptors.request.use(
  (config) => {
    // const token = store.getters['user/token']
    const token = ''
    // 规范写法 不可随意自定义
    if (token) config.headers['Authorization'] = `Bearer ${token}`
    console.log(config.url)
    if (debounce.some((item) => config.url.includes(item)))
      loadingInstance = Vue.prototype.$baseLoading()

    // config.data = qs.stringify(config.data) // 转为formdata数据格式
    return config
  },
  (error) => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)
/**
 * @description axios响应拦截器
 */
service.interceptors.response.use(
  (response) => handleData(response),
  (error) => {
    const { response } = error
    if (response === undefined) {
      console.error('未可知错误，大部分是由于后端不支持跨域CORS或无效配置引起')
      return {}
    } else return handleData(response)
  }
)

export default service

export function get(url) {
  return (params = {}, config) =>
    Promise.resolve(
      service
        .get(url, {
          ...config,
          params: params,
        })
        .then((response) => response)
    )
}

export function post(url) {
  return (data = {}, config) =>
    Promise.resolve(
      service.post(url, data, config).then((response) => {
        return response
      })
    )
}
// 给一些特殊的 post还要穿params
export function postParams(url) {
  return (params = {}, data = {}, config) =>
    Promise.resolve(
      service({ method: 'post', url: url, data, params, config }).then(
        (response) => {
          return response
        }
      )
    )
}
export function put(url) {
  return (data = {}, config) =>
    Promise.resolve(
      service.put(url, data, config).then((response) => {
        return response
      })
    )
}

export function filePOST(url) {
  return (data = {}, config) =>
    Promise.resolve(
      service({
        method: 'post',
        url,
        data,
        ...config,
      }).then((response) => response)
    )
}
